// origin repo: https://github.com/resyfer/libcol
#ifndef _COL_HOL_H_
#define _COL_HOL_H_

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>  // 新增：添加数学库头文件

// 平台检测
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/types.h>
#include <unistd.h>
#ifdef __APPLE__
#include <sys/ioctl.h>
#else
#include <termios.h>
#endif
#endif

// 工具宏
#define XSTR(X) #X
#define STR(X) XSTR(X)
#define COL_MAX_CTRL 128
#define COL_MAX_FORMATTED 4096
#define COL_RESET "\033[0m"  // 新增：定义RESET宏

// 颜色模式
typedef enum {
    COL_8,        // 8基础色
    COL_8_BRIGHT, // 8亮色调
    COL_256,      // 256色
    COL_RGB       // RGB真彩色
} col_mode_t;

// 文本样式
typedef enum {
    COL_NORMAL = 0,
    COL_BOLD = 1,
    COL_DIM = 2,
    COL_ITALIC = 3,
    COL_UNDERLINE = 4,
    COL_BLINK = 5,
    COL_REVERSE = 7,
    COL_HIDDEN = 8,
    COL_STRIKETHROUGH = 9,
    COL_DOUBLE_UNDERLINE = 21
} col_style_t;

// 8色基础颜色（前景）
typedef enum {
    COL_BLACK = 30,
    COL_RED = 31,
    COL_GREEN = 32,
    COL_YELLOW = 33,
    COL_BLUE = 34,
    COL_MAGENTA = 35,
    COL_CYAN = 36,
    COL_WHITE = 37
} col_8_t;

// 8色亮色调（前景）
typedef enum {
    COL_BRIGHT_BLACK = 90,
    COL_BRIGHT_RED = 91,
    COL_BRIGHT_GREEN = 92,
    COL_BRIGHT_YELLOW = 93,
    COL_BRIGHT_BLUE = 94,
    COL_BRIGHT_MAGENTA = 95,
    COL_BRIGHT_CYAN = 96,
    COL_BRIGHT_WHITE = 97
} col_8_bright_t;

// 8色基础颜色（背景）
typedef enum {
    COL_BG_BLACK = 40,
    COL_BG_RED = 41,
    COL_BG_GREEN = 42,
    COL_BG_YELLOW = 43,
    COL_BG_BLUE = 44,
    COL_BG_MAGENTA = 45,
    COL_BG_CYAN = 46,
    COL_BG_WHITE = 47
} col_bg_8_t;

// 8色亮色调（背景）
typedef enum {
    COL_BG_BRIGHT_BLACK = 100,
    COL_BG_BRIGHT_RED = 101,
    COL_BG_BRIGHT_GREEN = 102,
    COL_BG_BRIGHT_YELLOW = 103,
    COL_BG_BRIGHT_BLUE = 104,
    COL_BG_BRIGHT_MAGENTA = 105,
    COL_BG_BRIGHT_CYAN = 106,
    COL_BG_BRIGHT_WHITE = 107
} col_bg_8_bright_t;

// 光标方向
typedef enum {
    COL_UP,
    COL_DOWN,
    COL_LEFT,
    COL_RIGHT
} col_direction_t;

// 对齐方式
typedef enum {
    COL_ALIGN_LEFT,
    COL_ALIGN_CENTER,
    COL_ALIGN_RIGHT
} col_align_t;

// 函数声明
#ifdef __cplusplus
extern "C" {
#endif

// 初始化函数
void col_init(void);

// 颜色支持检测
bool col_supported(void);

// 获取终端尺寸
int col_term_width(void);
int col_term_height(void);

// 基础颜色控制
void col_set_fg_8(col_8_t color, char* buf);
void col_set_fg_8_bright(col_8_bright_t color, char* buf);
void col_set_bg_8(col_bg_8_t color, char* buf);
void col_set_bg_8_bright(col_bg_8_bright_t color, char* buf);

// 扩展颜色控制
void col_set_fg_256(int color_code, char* buf);
void col_set_bg_256(int color_code, char* buf);
void col_set_fg_rgb(unsigned char r, unsigned char g, unsigned char b, char* buf);
void col_set_bg_rgb(unsigned char r, unsigned char g, unsigned char b, char* buf);
void col_set_fg_hsl(float h, float s, float l, char* buf);
void col_set_bg_hsl(float h, float s, float l, char* buf);

// 样式控制
void col_set_style(col_style_t style, char* buf);
void col_reset(char* buf);

// 文本格式化
void col_format(const char* text, col_8_t color, col_style_t style, char* buf);
void col_format_advanced(const char* text,
                         col_mode_t fg_mode, int fg1, int fg2, int fg3,
                         col_mode_t bg_mode, int bg1, int bg2, int bg3,
                         col_style_t style, char* buf);

// 终端控制
void col_cursor_move(col_direction_t dir, int steps, char* buf);
void col_cursor_set(int row, int col, char* buf);
void col_cursor_hide(char* buf);
void col_cursor_show(char* buf);
void col_clear_screen(char* buf);
void col_clear_line(char* buf);
void col_scroll_up(int lines, char* buf);
void col_scroll_down(int lines, char* buf);
void col_set_title(const char* title, char* buf);

// 文本布局
void col_align(const char* text, col_align_t align, char* buf);
void col_pad(const char* text, int width, col_align_t align, char* buf);

#ifdef __cplusplus
}
#endif
#endif // _COL_HOL_H_

// 实现部分 - 仅在定义COL_IMPLEMENTATION时编译
#ifdef COL_IMPLEMENTATION

// 内部状态
static int col_support = -1;
static int col_width = 80;
static int col_height = 24;

// HSL转RGB辅助函数
static void hsl_to_rgb(float h, float s, float l, unsigned char* r, unsigned char* g, unsigned char* b) {
    float c = (1.0f - fabsf(2.0f * l - 1.0f)) * s;  // 修正：使用fabsf代替fabs
    float x = c * (1.0f - fabsf(fmodf(h / 60.0f, 2.0f) - 1.0f));  // 修正：使用fabsf
    float m = l - c / 2.0f;

    float rf = 0.0f, gf = 0.0f, bf = 0.0f;

    if (h >= 0 && h < 60) {
        rf = c; gf = x; bf = 0;
    } else if (h >= 60 && h < 120) {
        rf = x; gf = c; bf = 0;
    } else if (h >= 120 && h < 180) {
        rf = 0; gf = c; bf = x;
    } else if (h >= 180 && h < 240) {
        rf = 0; gf = x; bf = c;
    } else if (h >= 240 && h < 300) {
        rf = x; gf = 0; bf = c;
    } else if (h >= 300 && h < 360) {
        rf = c; gf = 0; bf = x;
    }

    *r = (unsigned char)((rf + m) * 255.0f);
    *g = (unsigned char)((gf + m) * 255.0f);
    *b = (unsigned char)((bf + m) * 255.0f);
}

// 初始化函数
void col_init(void) {
    if (col_support != -1) return;

#ifdef _WIN32
    // Windows平台初始化
    DWORD mode;
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

    if (hOut == INVALID_HANDLE_VALUE) {
        col_support = 0;
        return;
    }

    // 尝试启用VT100支持
    if (!GetConsoleMode(hOut, &mode)) {
        col_support = 0;
        return;
    }

    if (!SetConsoleMode(hOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) {
        col_support = 0;
        return;
    }

    // 获取终端尺寸
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if (GetConsoleScreenBufferInfo(hOut, &csbi)) {
        col_width = csbi.srWindow.Right - csbi.srWindow.Left + 1;
        col_height = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
    }

    col_support = 1;
#else
    // Unix-like平台初始化
    col_support = isatty(STDOUT_FILENO) ? 1 : 0;

    // 获取终端尺寸
#ifdef TIOCGWINSZ
    struct winsize w;
    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0) {
        col_width = w.ws_col;
        col_height = w.ws_row;
    }
#endif
#endif
}

// 检查颜色支持
bool col_supported(void) {
    if (col_support == -1) col_init();
    return col_support == 1;
}

// 获取终端宽度
int col_term_width(void) {
    if (col_support == -1) col_init();
    return col_width;
}

// 获取终端高度
int col_term_height(void) {
    if (col_support == -1) col_init();
    return col_height;
}

// 基础颜色设置
void col_set_fg_8(col_8_t color, char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[%dm", color);
}

void col_set_fg_8_bright(col_8_bright_t color, char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[%dm", color);
}

void col_set_bg_8(col_bg_8_t color, char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[%dm", color);
}

void col_set_bg_8_bright(col_bg_8_bright_t color, char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[%dm", color);
}

// 扩展颜色设置
void col_set_fg_256(int color_code, char* buf) {
    if (!col_supported() || color_code < 0 || color_code > 255) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[38;5;%dm", color_code);
}

void col_set_bg_256(int color_code, char* buf) {
    if (!col_supported() || color_code < 0 || color_code > 255) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[48;5;%dm", color_code);
}

void col_set_fg_rgb(unsigned char r, unsigned char g, unsigned char b, char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[38;2;%d;%d;%dm", r, g, b);
}

void col_set_bg_rgb(unsigned char r, unsigned char g, unsigned char b, char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[48;2;%d;%d;%dm", r, g, b);
}

void col_set_fg_hsl(float h, float s, float l, char* buf) {
    unsigned char r, g, b;
    hsl_to_rgb(h, s, l, &r, &g, &b);
    col_set_fg_rgb(r, g, b, buf);
}

void col_set_bg_hsl(float h, float s, float l, char* buf) {
    unsigned char r, g, b;
    hsl_to_rgb(h, s, l, &r, &g, &b);
    col_set_bg_rgb(r, g, b, buf);
}

// 样式控制
void col_set_style(col_style_t style, char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[%dm", style);
}

void col_reset(char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, COL_RESET);
}

// 文本格式化
void col_format(const char* text, col_8_t color, col_style_t style, char* buf) {
    if (!col_supported()) {
        snprintf(buf, COL_MAX_FORMATTED, "%s", text);
        return;
    }

    char color_buf[COL_MAX_CTRL];
    char style_buf[COL_MAX_CTRL];
    char reset_buf[COL_MAX_CTRL];

    col_set_fg_8(color, color_buf);
    col_set_style(style, style_buf);
    col_reset(reset_buf);

    snprintf(buf, COL_MAX_FORMATTED, "%s%s%s%s", style_buf, color_buf, text, reset_buf);
}

void col_format_advanced(const char* text,
                         col_mode_t fg_mode, int fg1, int fg2, int fg3,
                         col_mode_t bg_mode, int bg1, int bg2, int bg3,
                         col_style_t style, char* buf) {
    if (!col_supported()) {
        snprintf(buf, COL_MAX_FORMATTED, "%s", text);
        return;
    }

    char fg_buf[COL_MAX_CTRL] = "";
    char bg_buf[COL_MAX_CTRL] = "";
    char style_buf[COL_MAX_CTRL] = "";
    char reset_buf[COL_MAX_CTRL];

    col_reset(reset_buf);
    col_set_style(style, style_buf);

    // 设置前景色
    switch (fg_mode) {
        case COL_8:
            col_set_fg_8((col_8_t)fg1, fg_buf);
            break;
        case COL_8_BRIGHT:
            col_set_fg_8_bright((col_8_bright_t)fg1, fg_buf);
            break;
        case COL_256:
            col_set_fg_256(fg1, fg_buf);
            break;
        case COL_RGB:
            col_set_fg_rgb((unsigned char)fg1, (unsigned char)fg2, (unsigned char)fg3, fg_buf);
            break;
    }

    // 设置背景色
    switch (bg_mode) {
        case COL_8:
            col_set_bg_8((col_bg_8_t)bg1, bg_buf);
            break;
        case COL_8_BRIGHT:
            col_set_bg_8_bright((col_bg_8_bright_t)bg1, bg_buf);
            break;
        case COL_256:
            col_set_bg_256(bg1, bg_buf);
            break;
        case COL_RGB:
            col_set_bg_rgb((unsigned char)bg1, (unsigned char)bg2, (unsigned char)bg3, bg_buf);
            break;
    }

    snprintf(buf, COL_MAX_FORMATTED, "%s%s%s%s%s",
             style_buf, fg_buf, bg_buf, text, reset_buf);
}

// 终端控制
void col_cursor_move(col_direction_t dir, int steps, char* buf) {
    if (!col_supported() || steps <= 0) {
        buf[0] = '\0';
        return;
    }

    const char* dir_code;
    switch (dir) {
        case COL_UP: dir_code = "A"; break;
        case COL_DOWN: dir_code = "B"; break;
        case COL_RIGHT: dir_code = "C"; break;
        case COL_LEFT: dir_code = "D"; break;
        default: buf[0] = '\0'; return;
    }

    snprintf(buf, COL_MAX_CTRL, "\033[%d%s", steps, dir_code);
}

void col_cursor_set(int row, int col, char* buf) {
    if (!col_supported() || row < 1 || col < 1) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[%d;%dH", row, col);
}

void col_cursor_hide(char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[?25l");
}

void col_cursor_show(char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[?25h");
}

void col_clear_screen(char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[2J\033[1;1H");
}

void col_clear_line(char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[2K");
}

void col_scroll_up(int lines, char* buf) {
    if (!col_supported() || lines <= 0) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[%dS", lines);
}

void col_scroll_down(int lines, char* buf) {
    if (!col_supported() || lines <= 0) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033[%dT", lines);
}

void col_set_title(const char* title, char* buf) {
    if (!col_supported()) {
        buf[0] = '\0';
        return;
    }
    snprintf(buf, COL_MAX_CTRL, "\033]0;%s\007", title);
}

// 文本布局 - 修复函数调用错误
void col_align(const char* text, col_align_t align, char* buf) {
    col_pad(text, col_term_width(), align, buf);  // 修正：调用正确的函数
}

void col_pad(const char* text, int width, col_align_t align, char* buf) {
    int len = strlen(text);
    if (len >= width) {
        snprintf(buf, COL_MAX_FORMATTED, "%s", text);
        return;
    }

    int left = 0, right = 0;
    int pad = width - len;

    switch (align) {
        case COL_ALIGN_CENTER:
            left = pad / 2;
            right = pad - left;
            break;
        case COL_ALIGN_RIGHT:
            left = pad;
            break;
        case COL_ALIGN_LEFT:
        default:
            right = pad;
            break;
    }

    snprintf(buf, COL_MAX_FORMATTED, "%*s%s%*s", left, "", text, right, "");
}

#endif // COL_IMPLEMENTATION


/**
 * 这个实现遵循了 stb 风格的 header-only 库设计，主要特点和扩展功能如下：

 stb 风格实现：
 使用COL_IMPLEMENTATION宏控制实现部分的编译
 在需要编译实现的文件中，先定义#define COL_IMPLEMENTATION再包含头文件
 函数声明与实现分离，声明始终可见，实现仅在定义宏时编译
 扩展颜色支持：
 支持 4 种颜色模式：基础 8 色、亮色调 8 色、256 色和 RGB 真彩色
 新增 HSL 颜色支持（通过 HSL 转 RGB 实现）
 完整的前景色和背景色控制
 增强功能：
 终端滚动控制（向上 / 向下滚动）
 HSL 颜色空间支持（便于色彩调整）
 更完善的文本对齐和填充功能
 终端尺寸检测和使用
 跨平台特性：
 适配 Linux、macOS、BSD 和 Windows
 自动检测终端颜色支持能力
 在不支持 ANSI 转义的环境中自动降级
 */
